package com.hydra.auth.repository;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.nacos.common.utils.Objects;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hydra.auth.dto.menu.SysMenuTreeNodeDto;
import com.hydra.auth.entity.DictType;
import com.hydra.auth.entity.SysMenu;
import com.hydra.auth.entity.SysOperateLog;
import com.hydra.auth.mapper.SysMenuMapper;
import com.hydra.auth.mapper.SysOperateLogMapper;
import com.hydra.base.auth.UserRoleEnum;
import com.hydra.base.dto.auth.AuthRole;
import com.hydra.base.dto.auth.AuthUser;
import com.hydra.base.error.BusinessException;
import com.hydra.base.operate.log.annotation.OperateLogInject;
import com.hydra.base.operate.log.entity.BaseOperateLogEntity;
import com.hydra.base.services.BaseService;
import com.hydra.base.tree.TreeUtils;
import com.hydra.base.utils.RequestUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Repository
public class SysMenuService extends BaseService<SysMenu, SysMenuMapper> {

    @Resource
    private SysOperateLogMapper sysOperateLogMapper;

    /**切面进行操作日志记录*/
    @Override
    @OperateLogInject(cate = "SYS_MENU")
    public void handleOperateLog(SysMenu data, SysMenu history) {
        super.handleOperateLog(data, history);
    }

    /**保存操作日志*/
    @Override
    public void saveOperateLog(BaseOperateLogEntity operateLogInfo, SysMenu updateData, SysMenu historyData) {
        SysOperateLog log = operateLogInfo.copy(SysOperateLog.class);
        sysOperateLogMapper.insert(log);
    }

    /**
     * 获取当前用户的菜单
     */
    public List<SysMenuTreeNodeDto> getUserMenu(){
        List<SysMenuTreeNodeDto> menuList = getAllFlattingMenu();
        return TreeUtils.treeing(menuList);
    }

    /**
     * 获取角色的权限
     */
    private List<SysMenuTreeNodeDto> getAllFlattingMenu() {
        AuthUser authUser = RequestUtils.getAuthUser();
        if(authUser == null){
            throw new BusinessException("获取用户信息失败！");
        }
        List<AuthRole> roles = authUser.getRoles();
        if(CollectionUtils.isEmpty(roles)){
            throw new BusinessException("获取用户角色信息失败！");
        }
        List<String> roleCodes = roles.stream().map(AuthRole::getRoleCode).filter(Objects::nonNull).collect(Collectors.toList());
        //只有后台用户、管理员的权限才能获取菜单
        UserRoleEnum role = UserRoleEnum.findMaxRole(roleCodes);
        if(role.getValue() < UserRoleEnum.ROLE_USER.getValue()){
            log.info("用户权限不足！当前权限：{}， 需要权限：{}", roleCodes, UserRoleEnum.ROLE_USER.getCode());
            throw new BusinessException("用户权限不足！");
        }
        List<String> roleList = roles.stream().map(AuthRole::getRoleCode).collect(Collectors.toList());

        List<SysMenu> menuList = this.baseMapper.getUserMenuList(roleList, "bbs");

        if(CollectionUtils.isEmpty(menuList)){
            throw new BusinessException("获取菜单失败！该用户没有任何菜单权限");
        }

        return convertToVo(menuList);
    }


    /**
     * convertToVo
     * @param list list
     * @return List<SysMenuTreeNodeDto>
     */
    private List<SysMenuTreeNodeDto> convertToVo(List<SysMenu> list) {
        List<SysMenuTreeNodeDto> voList = new LinkedList<>();
        for (SysMenu menuBar : list) {
            SysMenuTreeNodeDto vo = new SysMenuTreeNodeDto();
            BeanUtil.copyProperties(menuBar, vo);
            vo.initSuperNodeId();
            vo.initSuperParentNodeId();
            voList.add(vo);
        }
        return voList;
    }

}
